using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Collections.Specialized;
using Ample.DAL;
using Ample.Model;

namespace Ample.BLL.User
{
    [System.ComponentModel.DataObject]
    public class BoardBO
    {
        #region Get Methods
        
        public IEnumerable<Board> GetBoards()
        {
            return DAL.User.BoardManager.Create().GetBoards();
        }

        public BoardUser GetBoardUserByBoardUserId(int id)
        {
            return DAL.User.BoardManager.Create().GetBoardUserByBoardUserId(id);
        }

        public IEnumerable<TreeBoardUser> GetTreeBoardUsersByBoardId(int id)
        {
            return DAL.User.BoardManager.Create().GetTreeBoardUsersByBoardId(id);
        }

        public IEnumerable<BoardUser> GetBoardUsersByBoardId(int id)
        {
            return DAL.User.BoardManager.Create().GetBoardUsersByBoardId(id);
        }

        public BoardUser GetParentBoardUserByBoardUserId(int id)
        {
            return DAL.User.BoardManager.Create().GetParentBoardUserByBoardUserId(id);
        }

        public IEnumerable<BoardUser> GetBoardWaitingUsersByBoardId(int boardId)
        {
            return DAL.User.BoardManager.Create().GetBoardWaitingUsersByBoardId(boardId);
        }

        public Board GetBoardById(int id)
        {
            return DAL.User.BoardManager.Create().GetBoardsById(id);
        }


        public Board GetBoardByCode(string code)
        {
            return DAL.User.BoardManager.Create().GetBoardsByCode(code);
        }

        public StringCollection GetBoardTypes()
        {
            var boards = new StringCollection();
            boards.AddRange(Enum.GetNames(typeof(EnumBoardType)));
            return boards;
        }

        public IEnumerable<BoardPosition> GetPositionsByLevel(string level)
        {
            return DAL.User.BoardManager.Create().GetBoardPositionsByLevel(level);
        }

        public IEnumerable<Board> GetPositionsByOpen(bool open)
        {
            return DAL.User.BoardManager.Create().GetBoardsByOpen(open);
        }

        public IEnumerable<BoardUser> GetChildBoardUsersByBoardUserId(int boardUserId)
        {
            return DAL.User.BoardManager.Create().GetChildBoardUsersByBoardUserId(boardUserId);
        }

        #endregion

        #region Delete Method

        public static void DeleteBoard(Board board)
        {
            OperationStatus opStatus = DAL.User.BoardManager.Create().DeleteBoard(board);
            if (!opStatus.Status)
            {
                throw new ApplicationException(String.Format("Error occurred in BLL.ProductRules.DeleteProduct: {0}", opStatus.Exception.Message));
            }
        }

        public static void DeleteBoardUser(BoardUser boardUser)
        {
            OperationStatus opStatus = DAL.User.BoardManager.Create().DeleteBoardUser(boardUser);
            if (!opStatus.Status)
            {
                throw new ApplicationException(String.Format("Error occurred in BLL.ProductRules.DeleteProduct: {0}", opStatus.Exception.Message));
            }
        }

        #endregion

        #region Save Method

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert, true)]
        public void SaveBoard(Board board)
        {
            OperationStatus opStatus = DAL.User.BoardManager.Create().SaveBoard(board);
            if (!opStatus.Status)
            {
                throw new ApplicationException(String.Format("Error occurred in BLL.User.SaveBoard: {0}", opStatus.Exception.Message));
            }
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert, true)]
        public void SaveBoardUser(BoardUser boardUser)
        {
            OperationStatus opStatus = DAL.User.BoardManager.Create().SaveBoardUser(boardUser);
            if (!opStatus.Status)
            {
                throw new ApplicationException(String.Format("Error occurred in BLL.User.SaveBoard: {0}", opStatus.Exception.Message));
            }

            ApplyBoardHierarchyRules(boardUser);
        }

        private static void ApplyBoardHierarchyRules(BoardUser boardUser)
        {
            var boardUsers = DAL.User.BoardManager.Create().GetBoardUsersByBoardId(boardUser.BoardId);
            
            var approvedBoardUsers = boardUsers.Where(b => b.Approved);
            
            if(approvedBoardUsers.Count() == 13)
            {
                var boardClosing = DAL.User.BoardManager.Create().GetBoardsById(boardUser.BoardId);
                boardClosing.Status = EnumBoardStatus.Closed.ToString();
                DAL.User.BoardManager.Create().UpdateStatus(boardClosing);
            
                //var yellowBoardUsers = approvedBoardUsers.Where(a => a.PositionCode.Contains(EnumPositionCodeType.Yellow.ToString()));

                var greenBoard = new Board();
                var yellowBoard1 = new Board();
                var yellowBoard2 = new Board();
                var yellowBoard3 = new Board();

                switch ((EnumBoardType)Enum.Parse(typeof(EnumBoardType), boardClosing.BoardTypeName, true))
                {
                    case EnumBoardType.Consultant:
                        
                        greenBoard.BoardTypeName = EnumBoardType.Manager.ToString();
                        yellowBoard1.BoardTypeName = EnumBoardType.Consultant.ToString();
                        yellowBoard2.BoardTypeName = EnumBoardType.Consultant.ToString();
                        yellowBoard3.BoardTypeName = EnumBoardType.Consultant.ToString();
                        break;
                    case EnumBoardType.Manager:
                        
                        greenBoard.BoardTypeName = EnumBoardType.Executive.ToString();
                        yellowBoard1.BoardTypeName = EnumBoardType.Manager.ToString();
                        yellowBoard2.BoardTypeName = EnumBoardType.Manager.ToString();
                        yellowBoard3.BoardTypeName = EnumBoardType.Manager.ToString();
                        break;
                }

                greenBoard.StartDate = DateTime.Now;
                yellowBoard1.StartDate = DateTime.Now;
                yellowBoard2.StartDate = DateTime.Now;
                yellowBoard3.StartDate = DateTime.Now;

                greenBoard.BoardCode = (Int32.Parse(boardClosing.BoardCode)*3 + 2).ToString();
                yellowBoard1.BoardCode = (Int32.Parse(boardClosing.BoardCode) * 3 - 1).ToString();
                yellowBoard2.BoardCode = (Int32.Parse(boardClosing.BoardCode) * 3).ToString();
                yellowBoard3.BoardCode = (Int32.Parse(boardClosing.BoardCode) * 3 + 1).ToString();

                foreach (var user in approvedBoardUsers)
                {
                    if (user.PositionCode.Contains("Green"))
                    {
                        var greenboarduser = new BoardUser();

                        greenboarduser.Board = greenBoard;
                        greenboarduser.Approved = true;
                        greenboarduser.Order = user.Order;
                        greenboarduser.PositionCode = "Red1";
                        greenboarduser.StartDate = DateTime.Now;
                        greenboarduser.UserId = user.UserId;

                        DAL.User.BoardManager.Create().SaveBoard(greenBoard);
                    }
                    else if (user.PositionCode.Contains("Yellow"))
                    {
                        var yellowboarduser = new BoardUser();

                        switch (user.PositionCode.Trim())
                        {
                            case "Yellow 1":
                                yellowboarduser.Board = yellowBoard1;
                                break;
                            case "Yellow 2":
                                yellowboarduser.Board = yellowBoard2;
                                break;
                            case "Yellow 3":
                                yellowboarduser.Board = yellowBoard3;
                                break;
                        }

                        yellowboarduser.Approved = true;
                        yellowboarduser.Order = user.Order;
                        yellowboarduser.PositionCode = "Green";
                        yellowboarduser.StartDate = DateTime.Now;
                        yellowboarduser.UserId = user.UserId;

                        var oldRedUsers = DAL.User.BoardManager.Create().GetChildBoardUsersByBoardUserId(user.BoardUserId);

                        foreach (var oldRedUser in oldRedUsers)
                        {
                            var redboarduser = new BoardUser();

                            redboarduser.Board = yellowboarduser.Board;
                            redboarduser.Approved = true;
                            redboarduser.Order = oldRedUser.Order;
                            
                            switch (oldRedUser.PositionCode.Trim())
                            {
                                case "Red 1":
                                    redboarduser.PositionCode = "Yellow 1";
                                    break;
                                case "Red 2":
                                    redboarduser.PositionCode = "Yellow 2";
                                    break;
                                case "Red 3":
                                    redboarduser.PositionCode = "Yellow 3";
                                    break;
                            }

                            redboarduser.StartDate = DateTime.Now;
                            redboarduser.UserId = oldRedUser.UserId;

                            redboarduser.ParentBoardUser = yellowboarduser;

                            //DAL.User.BoardManager.Create().SaveBoardUser(redboarduser);
                        }

                        DAL.User.BoardManager.Create().SaveBoard(yellowboarduser.Board);

                    }
                    //var newbrdylwusers = user.boardusers.where(u => u.positioncode.contains(enumpositioncodetype.red.tostring()));
                }
            }
        }

        #endregion
    }
}
